package com.ruoyi.service.impl;

import java.io.*;
import java.util.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.HttpURLConnection;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.nio.file.Path;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.service.AliyunAIService;
import io.minio.*;
import io.minio.http.Method;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.service.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import io.minio.StatObjectArgs;

/**
 * 阿里云AI服务实现类
 */
@Service
public class AliyunAIServiceImpl implements AliyunAIService {
    private static final Logger logger = LoggerFactory.getLogger(AliyunAIServiceImpl.class);

    @Value("${aliyun.ai.endpoint}")
    private String aiEndpoint;

    @Value("${aliyun.dashscope.api-key}")
    private String apiKey;

    @Value("${aliyun.ai.appId}")
    private Integer appId;

    @Value("${minio.endpoint}")
    private String minioEndpoint;

    @Value("${minio.access-key}")
    private String minioAccessKey;

    @Value("${minio.secret-key}")
    private String minioSecretKey;

    @Value("${aliyun.oss.endpoint}")
    private String ossEndpoint;

    @Value("${aliyun.oss.access-key-id}")
    private String ossAccessKeyId;

    @Value("${aliyun.oss.access-key-secret}")
    private String ossAccessKeySecret;

    private static final int MAX_RETRIES = 3;
    private static final int INITIAL_RETRY_DELAY_MS = 1000;
    private static final int CONNECTION_TIMEOUT_MS = 5000; // 5秒连接超时
    private static final int READ_TIMEOUT_MS = 30000;     // 30秒读取超时

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private FileStorageService fileStorageService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private MinioClient minioClient;

    @Override
    public String generateImageFromText(String prompt) throws Exception {
        return generateImageFromText(prompt, null);
    }

    @Override
    public String generateImageFromText(String prompt, String roomImageUrl) throws Exception {
        if (prompt == null || prompt.trim().isEmpty()) {
            throw new IllegalArgumentException("提示词不能为空");
        }

        logger.info("开始生成图片: prompt={}, roomImageUrl={}", prompt, roomImageUrl);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + apiKey);
        headers.set("X-DashScope-Async", "enable"); // 启用异步处理

        // 构建请求体
        Map<String, Object> requestBody = new HashMap<>();
        Map<String, Object> parameters = new HashMap<>();
        Map<String, Object> input = new HashMap<>();

        // 设置基本参数
        requestBody.put("model", "wanx2.1-imageedit");
        parameters.put("n", 1);
        parameters.put("watermark", false);   // 关闭水印

        // 如果有房间图片，使用线稿生图模式
        if (roomImageUrl != null && !roomImageUrl.trim().isEmpty()) {
            try {
                // 获取可公网访问的URL
                String publicUrl = getPublicAccessibleUrl(roomImageUrl);
                logger.info("转换后的公网可访问URL: {}", publicUrl);

                // 验证URL是否可访问
                validateImageUrl(publicUrl);

                // 设置线稿生图参数
                input.put("function", "doodle");
                input.put("prompt", prompt); // 直接使用中文提示词
                input.put("base_image_url", publicUrl);

                // 添加额外参数以提高成功率
                parameters.put("style_strength", 0.8);   // 设置风格强度
                parameters.put("image_quality", "high"); // 设置图片质量
                parameters.put("size", "1024*1024");     // 设置输出尺寸

                logger.info("使用线稿生图模式，base_image_url: {}", publicUrl);
            } catch (Exception e) {
                logger.error("处理房间图片失败: {}", e.getMessage(), e);
                throw new RuntimeException("处理房间图片失败: " + e.getMessage());
            }
        } else {
            // 如果没有房间图片，使用文生图模式
            input.put("function", "text2image");
            input.put("prompt", prompt); // 直接使用中文提示词
            parameters.put("size", "1024x1024"); // 设置输出尺寸
            parameters.put("image_quality", "high"); // 设置高质量输出
            parameters.put("style_strength", 0.8);   // 设置风格强度
            logger.info("使用文生图模式");
        }

        requestBody.put("input", input);
        requestBody.put("parameters", parameters);

        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);

        try {
            String apiUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/generation";
            if (roomImageUrl != null && !roomImageUrl.trim().isEmpty()) {
                apiUrl = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/image-synthesis";
            }
            logger.info("调用API URL: {}", apiUrl);
            logger.info("请求体: {}", objectMapper.writeValueAsString(requestBody));

            // 设置更长的超时时间
            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
            requestFactory.setConnectTimeout(60000); // 60秒连接超时
            requestFactory.setReadTimeout(120000);   // 120秒读取超时
            RestTemplate customRestTemplate = new RestTemplate(requestFactory);

            // 创建任务
            ResponseEntity<Map> response = customRestTemplate.exchange(
                    apiUrl,
                    HttpMethod.POST,
                    entity,
                    Map.class);

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                Map<String, Object> responseBody = response.getBody();
                logger.info("API响应: {}", objectMapper.writeValueAsString(responseBody));

                Map<String, Object> output = (Map<String, Object>) responseBody.get("output");

                if (output != null && output.containsKey("task_id")) {
                    String taskId = (String) output.get("task_id");
                    logger.info("成功创建任务，任务ID: {}", taskId);
                    return pollTaskResult(taskId);
                } else if (output != null && output.containsKey("results")) {
                    List<Map<String, Object>> results = (List<Map<String, Object>>) output.get("results");
                    if (results != null && !results.isEmpty()) {
                        String imageUrl = (String) results.get(0).get("url");
                        if (imageUrl != null && !imageUrl.trim().isEmpty()) {
                            return downloadImage(imageUrl);
                        }
                    }
                }
            }

            throw new RuntimeException("创建任务失败: " + response.getStatusCode());
        } catch (Exception e) {
            logger.error("API调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("图片生成失败: " + e.getMessage(), e);
        }
    }

    /**
     * 轮询任务结果
     */
    private String pollTaskResult(String taskId) throws Exception {
        String taskUrl = "https://dashscope.aliyuncs.com/api/v1/tasks/" + taskId;
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + apiKey);
        HttpEntity<Void> entity = new HttpEntity<>(headers);

        int maxAttempts = 30;
        int attempt = 0;
        int retryIntervalSeconds = 2;

        while (attempt < maxAttempts) {
            ResponseEntity<Map> response = restTemplate.exchange(
                taskUrl,
                HttpMethod.GET,
                entity,
                Map.class
            );

            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                Map<String, Object> responseBody = response.getBody();
                Map<String, Object> output = (Map<String, Object>) responseBody.get("output");

                if (output != null) {
                    String status = (String) output.get("task_status");

                    if ("SUCCEEDED".equals(status)) {
                        List<Map<String, Object>> results = (List<Map<String, Object>>) output.get("results");
                        if (results != null && !results.isEmpty()) {
                            String imageUrl = (String) results.get(0).get("url");
                            if (imageUrl != null && !imageUrl.trim().isEmpty()) {
                                return downloadImage(imageUrl);
                            }
                        }
                        throw new RuntimeException("任务成功但未找到图片URL");
                    } else if ("FAILED".equals(status)) {
                        String errorMessage = output.containsKey("message") ?
                            (String) output.get("message") : "Unknown error";
                        throw new RuntimeException("任务失败: " + errorMessage);
                    }
                }
            }

            attempt++;
            if (attempt < maxAttempts) {
                Thread.sleep(retryIntervalSeconds * 1000);
            }
        }

        throw new RuntimeException("等待任务完成超时");
    }

    @Override
    public String generateImageFromImage(MultipartFile sourceImage, String prompt) throws Exception {
        if (sourceImage == null || sourceImage.isEmpty()) {
            throw new IllegalArgumentException("源图片不能为空");
        }

        if (prompt == null || prompt.trim().isEmpty()) {
            throw new IllegalArgumentException("提示词不能为空");
        }

        logger.info("开始从图片生成新图片，提示词: {}, 原始文件名: {}", prompt, sourceImage.getOriginalFilename());

        try {
            // 上传源图片到MinIO获取URL
            String sourceImageUrl = fileStorageService.uploadImageFile(sourceImage.getOriginalFilename(), sourceImage.getInputStream());
            logger.info("已上传的源图片URL: {}", sourceImageUrl);

            // 使用图片URL生成新图片
            return generateImageFromText(prompt, sourceImageUrl);
        } catch (Exception e) {
            logger.error("从图片生成新图片失败: {}", e.getMessage(), e);
            throw new RuntimeException("从图片生成新图片失败: " + e.getMessage(), e);
        }
    }

    private String downloadImage(String imageUrl) throws Exception {
        OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .writeTimeout(60, TimeUnit.SECONDS)
            .retryOnConnectionFailure(true)
            .build();

        int retryCount = 0;
        int retryDelayMs = INITIAL_RETRY_DELAY_MS;
        byte[] imageData = null;

        while (retryCount < MAX_RETRIES && imageData == null) {
            try {
                logger.info("开始下载图片, URL: {}, 重试次数: {}", imageUrl, retryCount);

                Request request = new Request.Builder()
                    .url(imageUrl)
                    .header("User-Agent", "Mozilla/5.0")
                    .header("Accept", "image/png,image/*")
                    .build();

                try (Response response = client.newCall(request).execute()) {
                    if (!response.isSuccessful()) {
                        throw new RuntimeException("下载图片失败，HTTP状态码: " + response.code() +
                            ", 响应信息: " + response.message());
                    }

                    ResponseBody body = response.body();
                    if (body == null) {
                        throw new RuntimeException("响应体为空");
                    }

                    imageData = body.bytes();
                    if (imageData.length == 0) {
                        throw new RuntimeException("下载的图片数据为空");
                    }

                    logger.info("成功下载图片，大小: {} bytes", imageData.length);
                }
            } catch (Exception e) {
                logger.error("下载图片失败: {}", e.getMessage());
                retryCount++;

                if (retryCount < MAX_RETRIES) {
                    Thread.sleep(retryDelayMs);
                    retryDelayMs *= 2; // 指数退避
                } else {
                    throw new RuntimeException("下载图片失败，已达到最大重试次数: " + e.getMessage(), e);
                }
            }
        }

        if (imageData == null) {
            throw new RuntimeException("下载图片失败，未能获取有效数据");
        }

        // 生成唯一文件名
        String fileName = "generated_" + System.currentTimeMillis() + "_" +
            UUID.randomUUID().toString().substring(0, 8) + ".png";

        // 保存到MinIO
        String minioBucketName = "ai-paintings";
        String minioObjectName = "generated/" + fileName;

        // 使用FileStorageService进行文件上传
        try {
            String savedUrl = fileStorageService.uploadImageBytes(fileName, imageData);
            logger.info("图片成功保存到MinIO, 文件名: {}, URL: {}", fileName, savedUrl);
            return savedUrl;
        } catch (Exception e) {
            logger.error("保存图片到MinIO失败: {}", e.getMessage());
            // 如果是连接重置错误，尝试使用备用方法上传
            if (e.getMessage().contains("Connection reset")) {
                try {
                    logger.info("尝试使用备用方法上传图片...");
                    return uploadWithRetry(minioBucketName, minioObjectName, imageData);
                } catch (Exception retryEx) {
                    logger.error("备用上传方法也失败: {}", retryEx.getMessage());
                    throw new RuntimeException("保存图片到MinIO失败: " + e.getMessage(), e);
                }
            }
            throw new RuntimeException("保存图片到MinIO失败: " + e.getMessage(), e);
        }
    }

    /**
     * 使用重试机制的备用上传方法
     */
    private String uploadWithRetry(String bucketName, String objectName, byte[] data) throws Exception {
        int maxRetries = 3;
        int retryCount = 0;
        long retryDelayMs = 1000;

        while (retryCount < maxRetries) {
            try {
                // 使用单次上传，但增加重试机制
                try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
                    minioClient.putObject(
                        PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .stream(bis, data.length, -1)
                            .contentType("image/png")
                            .build()
                    );
                }

                // 生成预签名URL
                String savedUrl = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .method(Method.GET)
                        .expiry(7, TimeUnit.DAYS)
                        .build()
                );

                logger.info("备用方法成功保存图片到MinIO");
                return savedUrl;

            } catch (Exception e) {
                logger.error("第{}次上传尝试失败: {}", retryCount + 1, e.getMessage());
                retryCount++;

                if (retryCount < maxRetries) {
                    Thread.sleep(retryDelayMs);
                    retryDelayMs *= 2;
                } else {
                    throw e;
                }
            }
        }

        throw new RuntimeException("上传失败，已达到最大重试次数");
    }

    private String generatePresignedUrl(String bucketName, String objectName) throws Exception {
        try {
            // 创建新的MinIO客户端，确保使用正确的凭证
            MinioClient tempClient = MinioClient.builder()
                .endpoint(minioEndpoint)
                .credentials(minioAccessKey, minioSecretKey)
                .build();

            // 验证对象是否存在
            StatObjectArgs statObjectArgs = StatObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();

            // 先尝试获取对象以验证其存在性
            tempClient.statObject(statObjectArgs);

            // 获取对象内容
            GetObjectArgs getObjectArgs = GetObjectArgs.builder()
                .bucket(bucketName)
                .object(objectName)
                .build();

            // 直接从MinIO获取对象内容
            try (InputStream stream = tempClient.getObject(getObjectArgs)) {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = stream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                byte[] data = outputStream.toByteArray();

                // 检查数据大小
                if (data.length == 0) {
                    throw new RuntimeException("读取到的图片数据为空");
                }

                // 记录原始图片大小
                logger.info("原始图片大小: {} bytes", data.length);

                // 转换为Base64并确保没有换行符或空白字符
                String base64Data = Base64.getEncoder().encodeToString(data)
                    .replaceAll("\\s+", "")
                    .replaceAll("\n", "")
                    .replaceAll("\r", "");

                // 记录Base64编码后的长度
                logger.info("Base64编码后的长度: {} characters", base64Data.length());

                return base64Data;
            }
        } catch (Exception e) {
            logger.error("访问MinIO对象失败: {}", e.getMessage());
            throw new RuntimeException("无法访问图片: " + e.getMessage());
        }
    }

    /**
     * 获取可公网访问的URL
     */
    private String getPublicAccessibleUrl(String originalUrl) throws Exception {
        try {
            if (originalUrl == null || originalUrl.trim().isEmpty()) {
                throw new IllegalArgumentException("URL不能为空");
            }

            // 处理Base64编码的图片数据
            if (originalUrl.startsWith("data:image/") || isBase64Image(originalUrl)) {
                logger.info("检测到Base64图片数据，开始处理...");
                return handleBase64Image(originalUrl);
            }

            // 如果URL已经是HTTPS，且不是MinIO的内部URL，直接返回
            if (originalUrl.startsWith("https://") &&
                !originalUrl.contains("minio") &&
                !originalUrl.contains("114.55.56.174")) {
                return originalUrl;
            }

            // 如果是MinIO的URL，需要生成预签名URL
            if (originalUrl.contains("minio") || originalUrl.contains("114.55.56.174")) {
                URL url = new URL(originalUrl);
                String path = url.getPath();

                // 移除开头的斜杠
                if (path.startsWith("/")) {
                    path = path.substring(1);
                }

                // 分离bucket和object名称
                String bucketName;
                String objectName;

                int firstSlashIndex = path.indexOf('/');
                if (firstSlashIndex == -1) {
                    throw new IllegalArgumentException("Invalid MinIO URL format: " + originalUrl);
                }

                bucketName = path.substring(0, firstSlashIndex);
                objectName = path.substring(firstSlashIndex + 1);

                // URL解码object名称
                objectName = UriUtils.decode(objectName, StandardCharsets.UTF_8.name());

                logger.info("从URL解析: bucket={}, object={}", bucketName, objectName);

                try {
                    // 验证对象是否存在
                    minioClient.statObject(
                        StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build()
                    );

                    // 生成7天有效期的预签名URL
                    String presignedUrl = minioClient.getPresignedObjectUrl(
                        GetPresignedObjectUrlArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .method(Method.GET)
                            .expiry(7, TimeUnit.DAYS)
                            .build()
                    );

                    logger.info("生成预签名URL成功: {}", presignedUrl);
                    return presignedUrl;
                } catch (Exception e) {
                    logger.error("生成MinIO预签名URL失败: {}", e.getMessage());
                    throw new RuntimeException("无法访问MinIO中的图片: " + e.getMessage());
                }
            }

            // 如果是HTTP URL，尝试转换为HTTPS
            if (originalUrl.startsWith("http://")) {
                String httpsUrl = "https://" + originalUrl.substring(7);
                logger.info("将HTTP URL转换为HTTPS: {} -> {}", originalUrl, httpsUrl);
                return httpsUrl;
            }

            // 其他情况，尝试作为Base64处理
            if (isBase64Image(originalUrl)) {
                return handleBase64Image(originalUrl);
            }

            throw new IllegalArgumentException("不支持的URL格式: " + originalUrl);
        } catch (Exception e) {
            logger.error("处理URL失败: {}", e.getMessage());
            throw e;
        }
    }

    /**
     * 检查字符串是否为Base64编码的图片
     */
    private boolean isBase64Image(String data) {
        try {
            if (data.startsWith("data:image/")) {
                return true;
            }
            // 检查是否是Base64格式
            String base64Data = data;
            if (data.contains(",")) {
                base64Data = data.split(",")[1];
            }
            Base64.getDecoder().decode(base64Data);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 处理Base64编码的图片数据
     */
    private String handleBase64Image(String base64Data) throws Exception {
        try {
            logger.info("开始处理Base64图片数据...");

            // 提取实际的Base64数据
            String actualBase64;
            String imageFormat = null;

            if (base64Data.contains(",")) {
                String[] parts = base64Data.split(",");
                // 从header中提取格式信息
                if (parts[0].contains("image/")) {
                    imageFormat = parts[0].split("image/")[1].split(";")[0].toLowerCase();
                    logger.info("从Base64 header中检测到图片格式: {}", imageFormat);
                }
                actualBase64 = parts[1];
            } else {
                actualBase64 = base64Data;
            }

            // 移除可能存在的换行符和空格
            actualBase64 = actualBase64.replaceAll("\\s+", "")
                                     .replaceAll("\n", "")
                                     .replaceAll("\r", "");

            // 检查Base64数据是否为空
            if (actualBase64.isEmpty()) {
                throw new RuntimeException("Base64数据为空");
            }

            // 检查Base64数据的有效性
            byte[] imageData;
            try {
                imageData = Base64.getDecoder().decode(actualBase64);
                logger.info("Base64解码成功，数据大小: {} bytes", imageData.length);
            } catch (IllegalArgumentException e) {
                logger.error("Base64解码失败: {}", e.getMessage());
                throw new RuntimeException("无效的Base64数据格式: " + e.getMessage());
            }

            // 检查解码后的数据是否为空
            if (imageData == null || imageData.length == 0) {
                throw new RuntimeException("Base64解码后的数据为空");
            }

            // 如果没有从header中检测到格式，尝试从魔数检测格式
            if (imageFormat == null) {
                imageFormat = detectImageFormat(imageData);
                logger.info("从魔数检测到图片格式: {}", imageFormat);
            }

            // 使用临时文件处理图片
            Path tempFile = null;
            try {
                // 创建临时文件
                tempFile = Files.createTempFile("temp_image_", "." + imageFormat);
                Files.write(tempFile, imageData);
                logger.info("已创建临时文件: {}", tempFile);

                // 读取图片
                BufferedImage originalImage;
                try (ImageInputStream iis = ImageIO.createImageInputStream(tempFile.toFile())) {
                    Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
                    if (!readers.hasNext()) {
                        // 如果没有合适的reader，尝试使用其他格式
                        readers = ImageIO.getImageReadersByFormatName("PNG");
                    }

                    if (!readers.hasNext()) {
                        throw new RuntimeException("找不到合适的图片解码器");
                    }

                    ImageReader reader = readers.next();
                    try {
                        reader.setInput(iis);
                        originalImage = reader.read(0);
                    } finally {
                        reader.dispose();
                    }
                }

                if (originalImage == null) {
                    throw new RuntimeException("无法读取图片数据");
                }

                int originalWidth = originalImage.getWidth();
                int originalHeight = originalImage.getHeight();
                logger.info("成功读取图片，原始尺寸: {}x{}", originalWidth, originalHeight);

                // 检查并调整图片尺寸
                BufferedImage resizedImage = originalImage;
                if (originalHeight < 512 || originalHeight > 4096 || originalWidth < 512 || originalWidth > 4096) {
                    // 计算新的尺寸，保持宽高比但目标为1024x1024
                    int targetSize = 1024;
                    int targetWidth, targetHeight;

                    if (originalWidth > originalHeight) {
                        targetWidth = targetSize;
                        targetHeight = (int) (((double) targetSize / originalWidth) * originalHeight);
                    } else {
                        targetHeight = targetSize;
                        targetWidth = (int) (((double) targetSize / originalHeight) * originalWidth);
                    }

                    // 如果任一维度小于512，调整到最小512
                    if (targetWidth < 512) {
                        targetWidth = 512;
                        targetHeight = (int) (((double) targetWidth / originalWidth) * originalHeight);
                    }
                    if (targetHeight < 512) {
                        targetHeight = 512;
                        targetWidth = (int) (((double) targetHeight / originalHeight) * originalWidth);
                    }

                    logger.info("调整图片尺寸为: {}x{}", targetWidth, targetHeight);

                    // 创建新的图片
                    resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
                    Graphics2D g2d = resizedImage.createGraphics();

                    try {
                        // 设置高质量缩放
                        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                        g2d.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
                    } finally {
                        g2d.dispose();
                    }
                }

                // 将调整后的图片保存为PNG格式
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                if (!ImageIO.write(resizedImage, "PNG", baos)) {
                    throw new RuntimeException("无法将图片保存为PNG格式");
                }
                byte[] resizedImageData = baos.toByteArray();

                // 生成唯一的文件名
                String fileName = "upload_" + System.currentTimeMillis() + "_" +
                    UUID.randomUUID().toString().substring(0, 8) + ".png";

                // 使用FileStorageService保存图片
                try (ByteArrayInputStream bis = new ByteArrayInputStream(resizedImageData)) {
                    String savedUrl = fileStorageService.uploadImageFile(fileName, bis);
                    logger.info("Base64图片已保存到存储服务: {}", savedUrl);
                    return savedUrl;
                }
            } finally {
                // 清理临时文件
                if (tempFile != null) {
                    try {
                        Files.deleteIfExists(tempFile);
                        logger.info("已删除临时文件");
                    } catch (Exception e) {
                        logger.warn("删除临时文件失败: {}", e.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            logger.error("处理Base64图片数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("处理Base64图片数据失败: " + e.getMessage());
        }
    }

    /**
     * 从图片数据的魔数检测图片格式
     */
    private String detectImageFormat(byte[] imageData) {
        if (imageData == null || imageData.length < 8) {
            return "png"; // 默认返回PNG
        }

        // JPEG: FF D8 FF
        if (imageData[0] == (byte) 0xFF && imageData[1] == (byte) 0xD8 && imageData[2] == (byte) 0xFF) {
            return "jpeg";
        }

        // PNG: 89 50 4E 47 0D 0A 1A 0A
        if (imageData[0] == (byte) 0x89 && imageData[1] == (byte) 0x50 && imageData[2] == (byte) 0x4E &&
            imageData[3] == (byte) 0x47 && imageData[4] == (byte) 0x0D && imageData[5] == (byte) 0x0A &&
            imageData[6] == (byte) 0x1A && imageData[7] == (byte) 0x0A) {
            return "png";
        }

        // GIF: 47 49 46 38
        if (imageData[0] == (byte) 0x47 && imageData[1] == (byte) 0x49 && imageData[2] == (byte) 0x46 &&
            imageData[3] == (byte) 0x38) {
            return "gif";
        }

        // WebP: 52 49 46 46 ... 57 45 42 50
        if (imageData[0] == (byte) 0x52 && imageData[1] == (byte) 0x49 && imageData[2] == (byte) 0x46 &&
            imageData[3] == (byte) 0x46 && imageData[8] == (byte) 0x57 && imageData[9] == (byte) 0x45 &&
            imageData[10] == (byte) 0x42 && imageData[11] == (byte) 0x50) {
            return "webp";
        }

        // BMP: 42 4D
        if (imageData[0] == (byte) 0x42 && imageData[1] == (byte) 0x4D) {
            return "bmp";
        }

        return "png"; // 默认返回PNG
    }

    /**
     * 验证图片URL是否可访问
     */
    private void validateImageUrl(String imageUrl) throws Exception {
        try {
            // 如果是Base64图片数据，直接返回
            if (isBase64Image(imageUrl)) {
                return;
            }

            // 如果是MinIO URL，使用MinIO API验证
            if (imageUrl.contains("114.55.56.174:19000")) {
                try {
                    URL url = new URL(imageUrl);
                    String path = url.getPath();
                    if (path.startsWith("/")) {
                        path = path.substring(1);
                    }

                    // 分离bucket和object名称
                    String[] parts = path.split("/", 2);
                    if (parts.length != 2) {
                        throw new RuntimeException("Invalid MinIO URL format");
                    }

                    String bucketName = parts[0];
                    String objectName = parts[1];

                    // URL解码object名称
                    objectName = UriUtils.decode(objectName, StandardCharsets.UTF_8.name());

                    // 使用MinIO API验证对象是否存在
                    minioClient.statObject(
                        StatObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build()
                    );
                    return;
                } catch (Exception e) {
                    logger.error("MinIO对象验证失败: {}", e.getMessage());
                    throw new RuntimeException("MinIO对象验证失败: " + e.getMessage());
                }
            }

            // 对于其他URL，使用HTTP请求验证
            URL url = new URL(imageUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);

            int responseCode = connection.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK) {
                throw new RuntimeException("图片URL无法访问，响应码: " + responseCode);
            }

            String contentType = connection.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                throw new RuntimeException("URL不是有效的图片地址");
            }
        } catch (Exception e) {
            logger.error("验证图片URL失败: {}", e.getMessage());
            throw new RuntimeException("无效的图片URL: " + e.getMessage());
        }
    }
}
